/*
 * Copyright © 2020, PearX Team
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package com.gitee.wsl.collections.observable.handler

typealias ObservableHandlerSimple = () -> Unit

interface ObservableListHandler<T> : AbstractObservableCollectionHandler<T> {
    fun onAdd(index: Int, element: T)
    fun onRemove(index: Int, element: T)
    fun onSet(index: Int, prevValue: T, newValue: T)
}

private typealias ListElementBlock<T> = (index: Int, element: T) -> Unit
private typealias ListSetBlock<T> = (index: Int, prevElement: T, newElement: T) -> Unit

class ObservableListHandlerScope<T> : AbstractObservableCollectionHandlerScope<T>() {
    private var addBlock: ListElementBlock<T>? = null
    private var removeBlock: ListElementBlock<T>? = null
    private var setBlock: ListSetBlock<T>? = null

    fun add(block: ListElementBlock<T>) {
        addBlock = block
    }

    fun remove(block: ListElementBlock<T>) {
        removeBlock = block
    }

    fun set(block: ListSetBlock<T>) {
        setBlock = block
    }

    private inner class Handler : AbstractObservableCollectionHandlerScope<T>.Handler(),
        ObservableListHandler<T> {
        override fun onAdd(index: Int, element: T) {
            addBlock?.invoke(index, element)
        }

        override fun onRemove(index: Int, element: T) {
            removeBlock?.invoke(index, element)
        }

        override fun onSet(index: Int, prevValue: T, newValue: T) {
            setBlock?.invoke(index, prevValue, newValue)
        }
    }

    @PublishedApi
    internal fun createHandler(): ObservableListHandler<T> = Handler()
}

